package meb

import (
    "encoding/json"
    "fmt"
    "github.com/gin-gonic/gin"
    "github.com/stripe/stripe-go/v72"
    "github.com/stripe/stripe-go/v72/webhook"
    "io"
    "log/slog"
    "os"
	"time"
    "vitepress-serve/internal/common/hgin"
    "vitepress-serve/internal/model"
    "github.com/mosongcc/gotool/gtime"
)

// HandleStripeWebhook 处理 Stripe Webhook 回调
func (ctl *Controller) HandleStripeWebhook(ctx *gin.Context) (err error) {
    // 1. 读取请求体
    payload, err := io.ReadAll(ctx.Request.Body)
    if err != nil {
        slog.Error("读取请求体失败", "error", err)
        return fmt.Errorf("读取请求体失败: %w", err)
    }

    // 2. 获取签名
    sig := ctx.GetHeader("Stripe-Signature")
    if sig == "" {
        return fmt.Errorf("缺少 Stripe-Signature 头")
    }

    // 3. 验证签名
    endpointSecret := os.Getenv("STRIPE_WEBHOOK_SECRET")
    event, err := webhook.ConstructEvent(payload, sig, endpointSecret)
    if err != nil {
        slog.Error("验证 Webhook 签名失败",
            "error", err,
            "signature", sig,
        )
        return fmt.Errorf("验证 Webhook 签名失败: %w", err)
    }

    slog.Info("收到 Stripe Webhook 事件",
        "type", event.Type,
        "id", event.ID,
    )

    // 4. 处理事件
    switch event.Type {
    case "checkout.session.completed":
        var session stripe.CheckoutSession
        err := json.Unmarshal(event.Data.Raw, &session)
        if err != nil {
            slog.Error("解析会话数据失败", "error", err)
            return fmt.Errorf("解析会话数据失败: %w", err)
        }

        // 处理支付成功事件
        err = ctl.handlePaymentSuccess(&session)
        if err != nil {
            slog.Error("处理支付成功事件失败",
                "error", err,
                "sessionId", session.ID,
            )
            return fmt.Errorf("处理支付成功事件失败: %w", err)
        }
    }

    // 5. 返回成功
    hgin.ApiRes(ctx, gin.H{
        "status": "1",
        "message": "Webhook 处理成功",
    })
    return nil
}

// handlePaymentSuccess 处理支付成功事件
func (ctl *Controller) handlePaymentSuccess(session *stripe.CheckoutSession) error {
    // 1. 查询订单
    var order model.Order
    if err := ctl.db.Where("order_id = ?", session.ID).First(&order).Error; err != nil {
        slog.Error("查询订单失败", 
            "error", err,
            "sessionId", session.ID,
        )
        return fmt.Errorf("订单不存在: %w", err)
    }

    slog.Info("找到订单信息",
        "orderId", order.OrderId,
        "uid", order.Uid,
        "status", order.Status,
        "prodType", order.ProdType,
    )

    // 2. 检查订单状态
    if order.Status == model.ORDER_STATUS_PAID {
        slog.Info("订单已处理，跳过", 
            "orderId", order.OrderId,
            "status", order.Status,
            "payTime", order.PayTime,
        )
        return nil
    }

    // 3. 开启事务
    now := gtime.NowF14()
    tx := ctl.db.Begin()
    slog.Info("开始处理支付成功事务", "orderId", order.OrderId)

    // 4. 更新订单状态
    updateFields := map[string]interface{}{
        "status":    model.ORDER_STATUS_PAID,
        "pay_time":  now,
        "mtime":     now,
        "pay_type":  model.PayType_STRIPE_CARD,
        "pay_no":    session.ID,
        "prod_type": order.ProdType,
    }
    
    if err := tx.Model(&order).Updates(updateFields).Error; err != nil {
        tx.Rollback()
        slog.Error("更新订单状态失败",
            "error", err,
            "orderId", order.OrderId,
            "updateFields", updateFields,
        )
        return fmt.Errorf("更新订单状态失败: %w", err)
    }

    slog.Info("订单状态更新成功",
        "orderId", order.OrderId,
        "newStatus", model.ORDER_STATUS_PAID,
        "payTime", now,
    )

    // 5. 计算会员到期时间
    var vipDate string
    payTime, _ := time.Parse("20060102150405", now)
    switch order.ProdType {
    case model.ProductType_VIP_LONG:
        vipDate = "20991231" // 永久会员
    case model.ProductType_VIP_YEAR:
        vipDate = payTime.AddDate(1, 0, 0).Format("20060102")
    case model.ProductType_VIP_MONTH:
        vipDate = payTime.AddDate(0, 1, 0).Format("20060102")
    case model.ProductType_VIP_DAYS:
        vipDate = payTime.AddDate(0, 0, 30).Format("20060102")
    default:
        vipDate = payTime.Format("20060102")
    }

    slog.Info("计算会员到期时间",
        "uid", order.Uid,
        "prodType", order.ProdType,
        "vipDate", vipDate,
    )

    // 更新用户会员状态
    userUpdateFields := map[string]interface{}{
        "type":     model.USER_TYPE_VIP,
        "vip_date": vipDate,
        "mtime":    now,
    }

    if err := tx.Model(&model.User{}).Where("uid = ?", order.Uid).Updates(userUpdateFields).Error; err != nil {
        tx.Rollback()
        slog.Error("更新用户状态失败",
            "error", err,
            "uid", order.Uid,
            "updateFields", userUpdateFields,
        )
        return fmt.Errorf("更新用户状态失败: %w", err)
    }

    slog.Info("用户会员状态更新成功",
        "uid", order.Uid,
        "type", model.USER_TYPE_VIP,
        "vipDate", vipDate,
    )

    // 6. 提交事务
    if err := tx.Commit().Error; err != nil {
        slog.Error("提交事务失败",
            "error", err,
            "orderId", order.OrderId,
            "uid", order.Uid,
        )
        return fmt.Errorf("提交事务失败: %w", err)
    }

    slog.Info("支付成功处理完成",
        "orderId", order.OrderId,
        "uid", order.Uid,
        "prodType", order.ProdType,
        "vipDate", vipDate,
    )
    return nil
}